package exp5;

//---------------------------------------------------------------
//  MyDC.java   Author: 唐才铭   Date：2018-06-13
//
//  实现后缀表达式求值的功能。
//---------------------------------------------------------------

import java.util.Scanner;
import java.util.Stack;
import java.util.regex.Pattern;

public class MyDC {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        String another = "y";

        while (another.equalsIgnoreCase("y"))  //  allows y or Y
        {
            System.out.print("请输入后缀表达式：");
            String suffix = scanner.nextLine();
            String output  = suffixToArithmetic(suffix);
            System.out.print("计算结果为" + output);
            System.out.println();
            System.out.print("是否继续 (y/n)?");
            another = scanner.nextLine();
        }
    }

    // 将后缀表达式的进行计算得到运算结果 eg:325-6*3/+
    public static String suffixToArithmetic(String exp) {
        // 使用正则表达式匹配数字
        Pattern pattern = Pattern.compile("\\d+||(\\d+\\.\\d+)");
        // 将后缀表达式分割成字符串数组,此处直接使用空白也可以对字符串进行分割！！
        // String[] strings = exp.split("");
        String[] strings = exp.split(" ");

        Stack<Double> stack = new Stack<Double>();
        for (int i = 0; i < strings.length; i++) {
            // 这里最好是进行判断彻底消除空格，在该数组的第一位为一个隐形的空格，这里一定要注意在使用exp.split("")剔除空白""
            // 由于使用的是""截取导致在数组第一位上面的值为空白
            if (strings[i].equals(" ")) {
                continue;
            }
            // 如果遇到了数字则直接进栈
            if (pattern.matcher(strings[i]).matches()) {
                stack.push(Double.parseDouble(strings[i]));
            }
            // 如果是运算符，则弹出栈顶的两个数进行计算
            else {
                // ！！！这里需要注意，先弹出的那个数其实是第二个计算数值，这里记作y！
                // 自己书写的时候出错
                double y = stack.pop();
                double x = stack.pop();
                // 将运算结果重新压栈
                stack.push(calculate(x, y, strings[i]));
            }
        }
        String output = String.valueOf(stack.pop());
        // 弹出栈顶元素就是最终结果
        return output;
    }

    private static Double calculate(double x, double y, String string) {
        // TODO Auto-generated method stub
        // 其实使用case逻辑也可以
        if (string.trim().equals("+")) {
            return x + y; }
        else
        if (string.trim().equals("-")) {
            return x - y; }
        else
        if (string.trim().equals("*")) {
            return x * y; }
        else
        if (string.trim().equals("/")) {
            return x / y; }
        else
            return (double) 0;
    }
}